package com.resume.aipeople.service.ai;

import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * 百度语音服务实现
 * API文档：https://ai.baidu.com/ai-doc/SPEECH/Vk38lxily
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class BaiduVoiceService {
    
    @Value("${baidu.voice.api.key:your-baidu-api-key}")
    private String apiKey;
    
    @Value("${baidu.voice.secret.key:your-baidu-secret-key}")
    private String secretKey;
    
    @Value("${baidu.voice.app.id:your-app-id}")
    private String appId;
    
    private final WebClient webClient = WebClient.builder().build();
    
    /**
     * 获取百度Access Token
     */
    public Mono<String> getAccessToken() {
        String tokenUrl = "https://aip.baidubce.com/oauth/2.0/token";
        
        return webClient.post()
                .uri(uriBuilder -> uriBuilder
                        .path(tokenUrl)
                        .queryParam("grant_type", "client_credentials")
                        .queryParam("client_id", apiKey)
                        .queryParam("client_secret", secretKey)
                        .build())
                .retrieve()
                .bodyToMono(Map.class)
                .map(response -> (String) response.get("access_token"))
                .doOnError(error -> log.error("获取百度Access Token失败", error));
    }
    
    /**
     * 文本转语音 (TTS)
     */
    public Mono<byte[]> textToSpeech(String text, String characterName) {
        return getAccessToken()
                .flatMap(token -> {
                    String ttsUrl = "https://tsn.baidu.com/text2audio";
                    
                    Map<String, Object> params = new HashMap<>();
                    params.put("tex", text);
                    params.put("lan", "zh");
                    params.put("ctp", "1");
                    params.put("cuid", "aipeople");
                    params.put("tok", token);
                    params.put("per", selectVoiceForCharacter(characterName)); // 发音人选择
                    params.put("spd", "5"); // 语速
                    params.put("pit", "5"); // 音调
                    params.put("vol", "5"); // 音量
                    params.put("aue", "3"); // MP3格式
                    
                    return webClient.post()
                            .uri(ttsUrl)
                            .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                            .bodyValue(buildFormData(params))
                            .retrieve()
                            .bodyToMono(byte[].class);
                })
                .doOnError(error -> log.error("百度TTS转换失败", error));
    }
    
    /**
     * 语音识别 (ASR)
     */
    public Mono<String> speechToText(MultipartFile audioFile) {
        return getAccessToken()
                .flatMap(token -> {
                    try {
                        byte[] audioData = audioFile.getBytes();
                        String base64Audio = Base64.getEncoder().encodeToString(audioData);
                        
                        String asrUrl = "https://vop.baidu.com/server_api";
                        
                        Map<String, Object> params = new HashMap<>();
                        params.put("format", getAudioFormat(audioFile.getOriginalFilename()));
                        params.put("rate", 16000);
                        params.put("channel", 1);
                        params.put("cuid", "aipeople");
                        params.put("token", token);
                        params.put("speech", base64Audio);
                        params.put("len", audioData.length);
                        
                        return webClient.post()
                                .uri(asrUrl)
                                .contentType(MediaType.APPLICATION_JSON)
                                .bodyValue(params)
                                .retrieve()
                                .bodyToMono(BaiduASRResponse.class)
                                .map(response -> {
                                    if (response.getErr_no() == 0 && response.getResult() != null && !response.getResult().isEmpty()) {
                                        return response.getResult().get(0);
                                    }
                                    log.warn("百度ASR识别失败: {}", response.getErr_msg());
                                    return null;
                                });
                    } catch (IOException e) {
                        log.error("读取音频文件失败", e);
                        return Mono.just(null);
                    }
                })
                .doOnError(error -> log.error("百度ASR转换失败", error));
    }
    
    /**
     * 根据角色选择发音人
     */
    private String selectVoiceForCharacter(String characterName) {
        switch (characterName) {
            case "哈利波特":
                return "106"; // 男声
            case "苏格拉底":
                return "103"; // 磁性男声
            case "艾丽莎博士":
                return "110"; // 女声
            default:
                return "1"; // 普通女声
        }
    }
    
    /**
     * 获取音频格式
     */
    private String getAudioFormat(String filename) {
        if (filename != null && filename.toLowerCase().endsWith(".wav")) {
            return "wav";
        }
        return "amr"; // 默认格式
    }
    
    /**
     * 构建表单数据
     */
    private String buildFormData(Map<String, Object> params) {
        StringBuilder builder = new StringBuilder();
        params.forEach((key, value) -> {
            if (builder.length() > 0) {
                builder.append("&");
            }
            builder.append(key).append("=").append(value);
        });
        return builder.toString();
    }
    
    /**
     * 百度ASR响应类
     */
    @Data
    public static class BaiduASRResponse {
        private Integer err_no;
        private String err_msg;
        private String corpus_no;
        private java.util.List<String> result;
    }
} 